/*
 *
 *  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
 *  SPDX-License-Identifier: Apache-2.0
 *
 */
import { Button, Form, H3, Justify, Layout, Modal, Select, Table, TableColumn, Text } from 'tea-component';
import React, { useCallback, useContext, useEffect, useState } from 'react';
import { VoteManage, VotManageListRequest } from '../../common/apis/chains/interface';
import { formatDate } from '../../utils/date';
import {
  useFetchCertOrgList,
  useFetchVote,
  useFetchVoteManagementList,
  useFetchGetAdminList,
} from '../../common/apis/chains/hooks';
import { ChainDetailContext } from './chain-detail';
import { autotip, filterable, pageable } from 'tea-component/es/table/addons';
import { PAGE_SIZE_OPTIONS, tableFilter, splitUrl } from '../../utils/common';
import { useHistory } from 'react-router-dom';
import { TextTheme } from '../../common/components/upload-file';
import { ChainAuthTypes, VOTE_RULE_MAP, PublicChainAuthTypes } from './chain-auth';

const { Content } = Layout;

export function VoteResult({ voteResult }: { voteResult: number }) {
  return <>{voteResult ? '已投同意票' : '未投票'}</>;
}

export function VoteStatus({ record }: { record: { VoteStatus: number } | null }) {
  if (!record || !VOTE_STATUS_MAP[record.VoteStatus]) {
    return null;
  }
  const item = VOTE_STATUS_MAP[record.VoteStatus];
  return (
    <Text theme={item.theme} reset>
      {item.label}
    </Text>
  );
}

const defaultColumns = (onOperate: (vote: VoteManage) => void, isPublic: boolean): TableColumn<VoteManage>[] => [
  {
    key: 'CreateTime',
    header: '发起时间',
    render: (record) => formatDate(record.CreateTime),
  },
  {
    key: 'StartOrgName',
    header: isPublic ? '发起管理员' : '发起组织',
  },
  {
    key: 'VoteType',
    header: '投票事件',
    render: (record) => (isPublic ? PublicChainAuthTypes : ChainAuthTypes)[record.VoteType]?.title,
  },
  {
    key: 'PolicyType',
    header: '投票规则',
    render: (record) => VOTE_RULE_MAP[record.PolicyType]?.title,
  },
  {
    key: 'PassPercent',
    header: '当前通过率',
  },
  {
    key: 'VoteResult',
    header: '是否同意',
    // eslint-disable-next-line react/display-name
    render: (record) => <VoteResult voteResult={record.VoteResult} />,
  },
  {
    key: 'VoteStatus',
    header: '投票状态',
    // eslint-disable-next-line react/display-name
    render: (record) => <VoteStatus record={record} />,
  },
  {
    key: 'Id',
    header: '操作',
    // eslint-disable-next-line react/display-name
    render: (record) => <RecordOptions record={record} onOperate={onOperate} />,
  },
];

const VOTE_STATUS_MAP: {
  [index: number]: {
    theme: TextTheme;
    label: string;
  };
} = {
  0: {
    theme: 'warning',
    label: '投票中',
  },
  1: {
    theme: 'success',
    label: '投票完成',
  },
};

export default function ChainVotes() {
  const chainMode = String(splitUrl(location.search).get('chainMode') || '');
  const isPublic = chainMode === 'public';
  const { chainId } = useContext(ChainDetailContext);
  const [queryParams, setQueryParams] = useState<VotManageListRequest>({
    ChainId: chainId as string,
    ...(isPublic
      ? {
          AdminName: '',
        }
      : {
          OrgId: '',
        }),
    PageSize: 10,
    PageNum: 0,
    ChainMode: chainMode,
  });
  const [selectedVote, setSelectedVote] = useState<VoteManage | null>(null);

  const { orgList, run: fetchRecords } = useFetchCertOrgList();
  const {
    data: { list: voteList, totalCount },
    run: fetchVoteList,
  } = useFetchVoteManagementList();
  const [voteModalVisible, setVoteModalVisible] = useState(false);

  const { userList, fetchUserList } = useFetchGetAdminList();

  useEffect(() => {
    fetchRecords(chainId as string);
    fetchUserList(chainId as string);
  }, []);

  useEffect(() => {
    // 证书
    if (orgList.length) {
      setQueryParams({
        ...queryParams,
        OrgId: orgList[0].OrgId, // 默认选择第一个组织
      });
    }
    // 公钥
    if (userList.length) {
      setQueryParams({
        ...queryParams,
        AdminName: userList[0].AdminName, // 默认选择管理员
      });
    }
  }, [orgList, userList]);

  useEffect(() => {
    (queryParams.OrgId || queryParams.AdminName) && fetchVoteList(queryParams);
  }, [queryParams]);

  const onOrgChange = useCallback(
    (orgId: string) => {
      setQueryParams({
        ...queryParams,
        ...(isPublic
          ? {
              AdminName: orgId,
            }
          : {
              OrgId: orgId,
            }),
        PageNum: 0,
      });
    },
    [queryParams],
  );

  const onOperate = useCallback((vote: VoteManage) => {
    setSelectedVote(vote);
    setVoteModalVisible(true);
  }, []);

  return (
    <Content>
      <Content.Header title="区块链管理/投票管理" />
      <Content.Body full>
        <Justify
          left={
            <H3>
              {isPublic ? '切换投票管理员' : '切换投票组织'}
              <Select
                className={'tea-ml-3n'}
                onChange={onOrgChange}
                value={queryParams.OrgId || queryParams.AdminName}
                options={
                  isPublic
                    ? userList.map((item) => ({
                        text: item.AdminName || item.Addr,
                        value: item.AdminName || item.Addr,
                      }))
                    : orgList.map((item) => ({
                        text: item.OrgName,
                        value: item.OrgId,
                      }))
                }
              />
            </H3>
          }
        />
        <Table
          columns={defaultColumns(onOperate, isPublic)}
          records={voteList}
          className={'tea-mt-5n'}
          addons={[
            pageable({
              pageSizeOptions: PAGE_SIZE_OPTIONS,
              pageSize: queryParams.PageSize,
              pageIndex: queryParams.PageNum + 1,
              recordCount: totalCount,
              onPagingChange: ({ pageIndex, pageSize }) => {
                setQueryParams({
                  ...queryParams,
                  PageNum: (pageIndex as number) - 1,
                  PageSize: pageSize as number,
                });
              },
            }),
            filterable({
              type: 'single',
              column: 'VoteType',
              value: queryParams.VoteType === undefined ? tableFilter.all : String(queryParams.VoteType),
              onChange: (value) => {
                setQueryParams({
                  ...queryParams,
                  VoteType: value === tableFilter.all ? undefined : +value,
                  PageNum: 0,
                });
              },
              all: {
                value: tableFilter.all,
                text: '全部',
              },
              options: Object.entries(isPublic ? PublicChainAuthTypes : ChainAuthTypes).map((item) => ({
                text: item[1].title,
                value: String(item[0]),
              })),
            }),
            filterable({
              type: 'single',
              column: 'VoteStatus',
              value: queryParams.VoteStatus === undefined ? tableFilter.all : String(queryParams.VoteStatus),
              onChange: (value) => {
                setQueryParams({
                  ...queryParams,
                  VoteStatus: value === tableFilter.all ? undefined : (+value as 0 | 1),
                  PageNum: 0,
                });
              },
              all: {
                value: tableFilter.all,
                text: '全部',
              },
              options: Object.entries(VOTE_STATUS_MAP).map((item) => ({
                text: item[1].label,
                value: item[0],
              })),
            }),
            autotip({
              emptyText: '暂无数据',
            }),
          ]}
        />
        {selectedVote && (
          <VoteModal
            vote={selectedVote}
            onClose={() => setVoteModalVisible(false)}
            visible={voteModalVisible}
            onSubmit={() => {
              // 请先将该管理员信息导入到本平台，再进行投票
              fetchVoteList(queryParams);
              setVoteModalVisible(false);
            }}
          />
        )}
      </Content.Body>
    </Content>
  );
}

function RecordOptions({ record, onOperate }: { record: VoteManage; onOperate: (vote: VoteManage) => void }) {
  const chainMode = String(splitUrl(location.search).get('chainMode') || '');
  const history = useHistory();
  const { chainId } = useContext(ChainDetailContext);
  const handleViewClick = useCallback(() => {
    history.push(`/chains/${chainId}/votes/${record.Id}?chainMode=${chainMode}`);
  }, [record]);
  const handleReInvokeClick = useCallback(() => {
    onOperate(record);
  }, [record]);
  return (
    <>
      {[0].includes(record.VoteStatus) && record.VoteResult === 0 && (
        <Button type={'link'} onClick={handleReInvokeClick}>
          投票
        </Button>
      )}

      {
        <Button type={'link'} onClick={handleViewClick}>
          查看
        </Button>
      }
    </>
  );
}

function VoteModal(props: { vote: VoteManage; visible: boolean; onClose: () => void; onSubmit: () => void }) {
  const isPublic = String(splitUrl(location.search).get('chainMode') || '') === 'public';
  const [visible, setVisible] = useState(props.visible);
  const onClose = useCallback(() => {
    setVisible(false);
    props.onClose();
  }, [props]);
  const { run: doVote, loading } = useFetchVote(isPublic);
  useEffect(() => {
    setVisible(props.visible);
  }, [props.visible]);

  const handleSubmit = useCallback(async () => {
    await doVote({
      VoteId: props.vote.Id,
      VoteResult: 1,
    });
    setVisible(false);
    props.onSubmit();
  }, [props]);

  return (
    <Modal visible={visible} caption={'投票'} onClose={onClose}>
      <Modal.Body>
        <Form>
          <Form.Item label="投票事件">
            <Form.Text>{(isPublic ? PublicChainAuthTypes : ChainAuthTypes)[props.vote.VoteType].title}</Form.Text>
          </Form.Item>
          <Form.Item label="议案详情">
            <Form.Text>{props.vote.VoteDetail}</Form.Text>
          </Form.Item>
          <Form.Item label="投票原因">
            <Form.Text>{props.vote.Reason}</Form.Text>
          </Form.Item>
        </Form>
      </Modal.Body>
      <Modal.Footer>
        <Button onClick={onClose}>取消</Button>
        <Button type="primary" onClick={handleSubmit} loading={loading}>
          投同意票
        </Button>
      </Modal.Footer>
    </Modal>
  );
}
